package com.llbnk.service.impl;

import com.llbnk.dao.UserInfoDOMapper;
import com.llbnk.dao.UserPasswordDOMapper;
import com.llbnk.error.BusinessException;
import com.llbnk.error.EmBusinessError;
import com.llbnk.pojo.entity.UserInfoDO;
import com.llbnk.pojo.entity.UserPasswordDO;
import com.llbnk.pojo.model.UserModel;
import com.llbnk.service.UserService;
import com.llbnk.validator.ValidationResult;
import com.llbnk.validator.ValidatorImpl;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.concurrent.TimeUnit;

/**
 * @author llbnk
 * @create 2022-08-19 23:56
 */
@Service
@Slf4j
public class UserServiceImpl implements UserService{

    @Resource
    private UserInfoDOMapper userInfoDOMapper;

    @Resource
    private UserPasswordDOMapper userPasswordDOMapper;

    @Resource
    private ValidatorImpl validator;

    @Resource
    private RedisTemplate redisTemplate;

    @Override
    public UserModel getUserById(Integer id) {
        UserInfoDO userInfoDO = userInfoDOMapper.selectByPrimaryKey(id);
        if(userInfoDO == null) return null;
        //获取加密密码信息
        UserPasswordDO passwordDo = userPasswordDOMapper.selectByUserId(userInfoDO.getId());
        return convertFromDataObject(userInfoDO,passwordDo);
    }

    @Override
    @Transactional
    public void register(UserModel userModel) throws BusinessException {
        if(userModel == null){
            throw new BusinessException(EmBusinessError.PARAMETER_VALIDATION_ERROR);
        }
//        if(StringUtils.isEmpty(userModel.getName())
//                || userModel.getGender() == null
//                || userModel.getAge() == null
//                || StringUtils.isEmpty(userModel.getTelephone())){
//            throw new BusinessException(EmBusinessError.PARAMETER_VALIDATION_ERROR);
//        }
        ValidationResult result = validator.validate(userModel);
        if(result.isHasErrors()){
            throw new BusinessException(EmBusinessError.PARAMETER_VALIDATION_ERROR, result.getErrMsg());
        }

        //实现model->entity
        UserInfoDO userDO = convertFromModel(userModel);

        try {
            userInfoDOMapper.insertSelective(userDO);
        } catch (DuplicateKeyException e) {
            throw new BusinessException(EmBusinessError.PARAMETER_VALIDATION_ERROR,"手机号已经重复注册");
        }
        log.info("user_info表插入完成");
        userModel.setId(userDO.getId());
        log.info("userDO ["+userDO+"]");
        UserPasswordDO userPasswordDO = passwordConFromModel(userModel);
        log.info("userpasswordDO ["+userPasswordDO+"]");
        userPasswordDOMapper.insertSelective(userPasswordDO);
        log.info("user_password表插入完成");

        return;
    }

    @Override
    public void test() {
        UserInfoDO userInfoDO = new UserInfoDO();
        userInfoDO.setId(2);
        userInfoDO.setTelephone("1333333");
        userInfoDO.setName("wxx");
        userInfoDO.setGender(new Byte(String.valueOf(1)));
        userInfoDO.setAge(23);
        userInfoDO.setRegisterMode("byphone");
        userInfoDO.setThirdPartyId("1992");
        System.out.println(userInfoDO);
        userInfoDOMapper.insert(userInfoDO);
    }

    @Override
    public UserModel vaildateLogin(String telephone, String encrptPassword) throws BusinessException {
        //通过手机获取用户信息
        UserInfoDO userDO = userInfoDOMapper.selectByTelephone(telephone);
        if(userDO == null){
            throw new BusinessException(EmBusinessError.USER_LOGIN_FAIL);
        }
        UserPasswordDO userPasswordDO = userPasswordDOMapper.selectByUserId(userDO.getId());
        UserModel userModel = convertFromDataObject(userDO, userPasswordDO);

        //比对密码
        if(!StringUtils.equals(encrptPassword, userModel.getEncrptPassword())){
            throw new BusinessException((EmBusinessError.USER_LOGIN_FAIL));
        }
        return userModel;
    }

    /**
     * 用于给orderserviceImpl的createorder使用的
     * @param id
     * @return
     */
    @Override
    public UserModel getUserByIdInCache(Integer id) {
        UserModel userModel = (UserModel) redisTemplate.opsForValue().get("user_validate_"+id);
        if(userModel == null){
            userModel = this.getUserById(id);
            redisTemplate.opsForValue().set("user_validate_"+id,userModel);
            redisTemplate.expire("user_validate_"+id,10, TimeUnit.MINUTES);
        }
        return userModel;
    }


    //用于注册将前端传进来的model对象变成对应的Userpassword对象
    private UserPasswordDO passwordConFromModel(UserModel userModel) {
        if(userModel == null) return null;
        UserPasswordDO userPasswordDO = new UserPasswordDO();
        userPasswordDO.setUserId(userModel.getId());
        userPasswordDO.setEncrptPassword(userModel.getEncrptPassword());
        return userPasswordDO;
    }

    //用于注册将前端传进来的model对象变成对应的Userinfo对象
    private UserInfoDO convertFromModel(UserModel userModel) {
        if(userModel == null) return null;
        UserInfoDO userInfoDO = new UserInfoDO();
        BeanUtils.copyProperties(userModel,userInfoDO);
        return userInfoDO;
    }

    private UserModel convertFromDataObject(UserInfoDO userInfoDO,
                                            UserPasswordDO userPasswordDO){
        UserModel userModel = new UserModel();
        //a拷贝到b  BeanUtils.copyProperties(a, b);
        //BeanUtils.copyProperties方法简单来说就是将两个字段相同的对象进行属性值的复制。
        // 如果 两个对象之间存在名称不相同的属性，则 BeanUtils 不对这些属性进行处理，需要程序手动处理。
        BeanUtils.copyProperties(userInfoDO, userModel);
        if(userPasswordDO != null)
        userModel.setEncrptPassword(userPasswordDO.getEncrptPassword());
        return userModel;
    }
}
